package org.example.judge.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import lombok.Data;
import lombok.NonNull;
import org.example.judge.mapper.SubmitMapper;
import org.example.judge.oj.JudgeResult;
import org.example.judge.service.SubmitService;
import org.example.judge_common.entity.PageResult;
import org.example.judge_common.entity.RequestParams;
import org.example.judge_common.entity.RequestSubmitParams;
import org.example.judge_common.rank.AllUserRank;
import org.example.judge_common.util.IdWorker;
import org.example.judge_common.util.MyUtils;
import org.example.judge_pojo.Submit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.FileInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;

@Service("SubmitServiceImpl")
public class SubmitServiceImpl extends ServiceImpl<SubmitMapper, Submit> implements SubmitService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IdWorker idWorker;

    @Override
    public boolean save(Submit entity) {
        if(MyUtils.isEmpty(entity.getId()))entity.setId(idWorker.nextId().toString());
        // 提交的代码排队中
        entity.setStatus(1);
        entity.setCreateTime(new Date());
        if (entity.getShare()==null||entity.getShare()!=1) { //默认分享
            entity.setShare(0);
        }
        //代码长度
        entity.setLength(entity.getCode().length());
        entity.setErrorStatus(JudgeResult.RUNNING);  //运行中
        //语言转换为小写
//        entity.setLanguage(entity.getLanguage().toLowerCase());
//        首字母大写

        //将提交信息保存到redis,保存2分钟
        redisTemplate.opsForValue().set(entity.getId(), JSON.toJSONString(entity), 2, TimeUnit.MINUTES);

        //发送id到提交队列
        redisTemplate.opsForList().leftPush("submit", entity.getId());
        // 保存到数据库
        return super.save(entity);
    }

    @Override
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

    @Override
    public boolean updateById(Submit entity) {
//        if(MyUtils.isNotEmpty(entity.getCode()))entity.setLength(entity.getCode().length());
        //将提交信息保存到redis,保存两分钟
        redisTemplate.opsForValue().set(entity.getId(), JSON.toJSONString(entity), 2, TimeUnit.MINUTES);
        return super.updateById(entity);
    }

    @Override
    public Submit getById(Serializable id) {
        Object o1 = redisTemplate.opsForValue().get(id);
        Submit o = null;
        if(o1==null){
            o = super.getById(id);
            if(o==null)return o;
            //将提交信息保存到redis,保存两分钟
            redisTemplate.opsForValue().set(o.getId(), JSON.toJSONString(o), 1, TimeUnit.MINUTES);
        }else o = JSON.parseObject((String) o1,Submit.class);
        return o;
    }


    @Override
    public PageResult<Submit> search(RequestSubmitParams params) {
        if(MyUtils.isEmpty(params.getField())){ //默认排序字段
            params.setField("create_time");
        }
        if(MyUtils.isEmpty(params.getOrder())){   //默认排序方式
            params.setOrder(RequestParams.DESC);
        }

        QueryWrapper<Submit> queryWap = new QueryWrapper<>();

        //字段模糊匹配
//        if(MyUtils.isNotEmpty(params.getKey())){
//            queryWap.and(new Consumer<QueryWrapper<Problem>>() { //隔离or条件
//                @Override
//                public void accept(QueryWrapper<Problem> problemQueryWrapper) {
//                    problemQueryWrapper.like("title",params.getKey()).or().like("description",params.getKey());
//                }
//            });
//
//        }

        // 用户id
        if (MyUtils.isNotEmpty(params.getUserId())) {
            queryWap.eq("user_id", params.getUserId());
        }
        // 比赛id
        if(MyUtils.isNotEmpty(params.getContestId())){
            queryWap.eq("contest_id", params.getContestId());
        }
        // 题目id
        if(params.getProblemId()!=null&&params.getProblemId().length>0){
            queryWap.in("problem_id",params.getProblemId());
        }
        // 语言,转换为小写
        if(MyUtils.isNotEmpty(params.getLanguage())){
            queryWap.and(new Consumer<QueryWrapper<Submit>>() { //隔离or条件
                @Override
                public void accept(QueryWrapper<Submit> problemQueryWrapper) {
                    problemQueryWrapper.eq("language",params.getLanguage().toLowerCase()).or().
                            eq("language",params.getLanguage());
                }
            });
//            queryWap.eq("language",params.getLanguage().toLowerCase());
        }
        // 运行结果
        if(params.getErrorStatus()!=null){
            queryWap.eq("error_status",params.getErrorStatus());
        }

        //排序
        queryWap.orderBy(true,"asc".equalsIgnoreCase(params.getOrder()),params.getField());


        //设置分页
        PageHelper.startPage(params.getPage(), params.getSize(),false);
        List<Submit> problems = this.baseMapper.selectList(queryWap);
        //求数据条数
        Integer count = this.baseMapper.selectCount(queryWap);
//        System.out.println(problems.size());
        return new PageResult<Submit>(count.longValue(),problems);
    }

    @Override
    public Integer getSumByProblem(String problemId) {
        QueryWrapper<Submit> submitQueryWrapper = new QueryWrapper<>();
        submitQueryWrapper.eq("problem_id",problemId).ne("status","-1");
        return super.count(submitQueryWrapper);
    }

    @Override
    public Integer getAccessSumByProblem(String problemId) {
        QueryWrapper<Submit> submitQueryWrapper = new QueryWrapper<>();
        submitQueryWrapper.eq("problem_id",problemId);
        submitQueryWrapper.eq("error_status",0).ne("status","-1");
        return super.count(submitQueryWrapper);
    }

    @Override
    public Integer getSuccessProblemSum(String userId, boolean pass) {
        QueryWrapper<Submit> submitQueryWrapper = new QueryWrapper<>();
        submitQueryWrapper.eq("user_id",userId);
        if(pass)submitQueryWrapper.eq("error_status",0);
        submitQueryWrapper.ne("status","-1");
//        submitQueryWrapper.groupBy("problem_id");
        submitQueryWrapper.select("DISTINCT problem_id");
        return super.count(submitQueryWrapper);
    }

    @Override
    public Integer getSumbitSum( String problemId, String userId, Integer errorStatus) {
        QueryWrapper<Submit> submitQueryWrapper = new QueryWrapper<>();
        if(MyUtils.isNotEmpty(problemId))submitQueryWrapper.eq("problem_id",problemId);
        submitQueryWrapper.eq("user_id",userId);
        submitQueryWrapper.ne("status","-1");
        if(errorStatus!=null)submitQueryWrapper.eq("error_status",errorStatus);
        return super.count(submitQueryWrapper);
    }

    @Override
    public Submit lastSubmit(String problemId, String userId) {
        QueryWrapper<Submit> submitQueryWrapper = new QueryWrapper<>();
        submitQueryWrapper.eq("problem_id",problemId).eq("user_id",userId);
        submitQueryWrapper.orderBy(true,false,"create_time");
        PageHelper.startPage(1,1,false);
        return super.getOne(submitQueryWrapper);
    }

    @Override
    public PageResult<AllUserRank> getAllUserRankSubmit(Integer page, Integer size,String beginTime) {
        if(page==null||page<1)page = 1;
        if(size==null)size = 10;
        if(MyUtils.isEmpty(beginTime))beginTime = "1970-01-01";
        List<AllUserRank> allRankSumbit = super.baseMapper.getAllRankSumbit((page - 1) * size, size,beginTime);

        return new PageResult<AllUserRank>(0l,allRankSumbit);
    }

    @Override
    public List<String> getNoAcceept(String userId) {

        return super.baseMapper.getNotAcceptProblemIds(userId);
    }
}
